

export default function timeZoneTrans(input){
  let isISO, dateData, date, srcTimezone, localeTimezone;
  isISO = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\./.test(input);
  dateData = analyzeDate(input, isISO);
  date = dateData.date;
  srcTimezone = dateData.timezone;
  localeTimezone = getLocaleTimezone();
  changeTimeZone(date, srcTimezone, localeTimezone);
  return dateSerialize(date, !isISO, localeTimezone);
}

/***
 * 日期序列化
 * @param {Date} date
 * @param {boolean} toISO
 * @param {number} timezone 经过正负转换的时区，例如'+0800'为-8
 * @returns {string}
 */
function dateSerialize(date, toISO, timezone){
  let result;
  let year = date.getFullYear();
  let month = prefixPaddedZeros((date.getMonth() + 1), 2);
  let d = prefixPaddedZeros(date.getDate(), 2);
  let hours = prefixPaddedZeros(date.getHours(), 2);
  let minutes = prefixPaddedZeros(date.getMinutes(), 2);
  let seconds = prefixPaddedZeros(date.getSeconds(), 2);
  let milliseconds = prefixPaddedZeros(date.getMilliseconds(), 3);
  if (!toISO) {
    result = year + '/' + month + '/' + d + ' ' + hours + ':' + minutes + ':' + seconds;
  } else {
    result = year + '-' + month + '-' + d + 'T' + hours + ':' + minutes + ':' + seconds + '.' + milliseconds + timezoneNum2Str(timezone);
  }
  return result;
}

/***
 * 解析日期字符串
 * @param dateStr {string}
 * @param isISO {boolean} 是否是ISO格式
 * @returns {{date: Date, timezone: number}}
 */
function analyzeDate(dateStr, isISO){
  let tmp, date, time, timezone;
  let reg;

  if (isISO) {
    reg = /T|\./;
  } else {
    reg = /\s/;
  }

  tmp = dateStr.split(reg);
  date = tmp[0].replace(/-/g, '/');
  time = tmp[1];

  if (tmp[2]) {
    timezone = timezoneStr2Num(tmp[2].substr(-5, tmp[2].length));
  } else {
    timezone = getLocaleTimezone()
  }
  return {
    date: new Date(date + ' ' + time),
    timezone: timezone
  }
}

/**
 * 获取本地时区
 * @returns {number} 以小时为单位的区时表示
 */
function getLocaleTimezone(){
  return (new Date()).getTimezoneOffset() / 60;
}

/**
 * 将当前操作的时间变更时区
 *
 * @param {Date} date
 * @param {int} tzo 原时区 -12~13
 * @param {int} tzn 目标时区 -12~13 默认为当前时区
 */
function changeTimeZone(date, tzo, tzn){
  let offset = (tzo - tzn) * 3600 * 1000;
  date.setTime(date.getTime() + offset);
}

/***
 * 时区字符串转换为数字，同时进行正负转换，例如'+0800' -> -8
 * @param tzStr {string}
 * @returns {number}
 */
function timezoneStr2Num(tzStr){
  let hours = tzStr.substr(0, 3);
  let minutes = tzStr.substr(3, 5);
  return -(parseInt(hours, 10) + parseInt(minutes, 10) / 60);
}

/***
 * 时区数字转换为字符串，同时还原正负符号，例如-8 -> '+0800'
 * @param tzNum {number}
 * @returns {string}
 */
function timezoneNum2Str(tzNum){
  let symbol;
  let hours, minutes;
  symbol = tzNum < 0 ? '+' : '-';
  minutes = tzNum.toFixed(2).substr(-2, tzNum.length) / 100 * 60;
  hours = Math.abs(parseInt(tzNum, 10)).toString();
  return symbol + prefixPaddedZeros(hours, 2) + prefixPaddedZeros(minutes, 2);
}

/**
 * 前导零填充
 * @param value {number}
 * @param width {number}
 * @returns {string}
 */
function prefixPaddedZeros(value, width){
  let leadingZeroes = function(){
    let zeros = '';
    for (let i = 0; i < width; i++) {
      zeros += '0';
    }
    return zeros;
  }();
  return (leadingZeroes + (value || 0)).slice(-width);
}

